﻿using glb;
using PIMS;
using PIMS.DBModel;
using PIMS.iniUtil;
using PIMS.Interface;
using PIMS.QRCODE;
using PIMS.Utils;
using PIMS.WorkPlugin.ORM;
using PIMS.XmlModel;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Printing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using ZXing;
using ZXing.Common;

namespace PIMS.Print
{
    public partial class FormPrint : Form
    {
        private DataTable data=null;
        private int index = 0;
        string barcode = "";

        string head = "X3P";
        string regkeypath = @"SOFTWARE\YongXiangProject\FormPrint";
        private string configFile = AppDomain.CurrentDomain.BaseDirectory + "离线打印机配置.ini";
        private string lableConfigFile = AppDomain.CurrentDomain.BaseDirectory + "袋标签配置.xml";
        string 生产批次号="";
        string 模板ID="";

        iniOper iniHistory;
        PrintDocument Printer = new PrintDocument();
        Bitmap qrBmp;
        Graphics gdi;
        Bitmap image;
        int width;
        int height;

        private IDebugMsg debug = null;
        private ILog4net log = null;
        XmlDocument xmlDocument = new XmlDocument();
        PIMSConfigX pimsConfig = null;

        string head1 = "";
        string head2 = "";

        public FormPrint()
        {
            InitializeComponent();
            pimsConfig = XmlHelper.XmlFileToObject<PIMSConfigX>(AppDomain.CurrentDomain.BaseDirectory + "config\\PIMSConfig.xml");
        }

        public FormPrint(DataTable dt,int rowIndex)
        {
            InitializeComponent();
            this.data = dt;
            this.index = rowIndex;

            if (rowIndex == 0)
            {
                head = head1;
            }
            else if (rowIndex == 1)
            {
                head = head2;
            }
        }

        /// <summary>
        /// 注：反射加载时会自动调用一次
        /// </summary>
        public void Init(IDebugMsg debugMsg, ILog4net log4net)
        {
            this.debug = debugMsg;
            this.log = log4net;
        }

        private void FormPrint_Load(object sender, EventArgs e)
        {
            //dateTimePicker1.MinDate = DateTime.Now.AddDays(-1);
            dateTimePicker1.Value = DateTime.Now;
            //dateTimePicker1.MaxDate = DateTime.Now.AddDays(1);
            

            if (!File.Exists(configFile))
            {
                MessageBox.Show("离线打印机配置.ini丢失！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                this.Close();
            }
            if (!File.Exists(lableConfigFile))
            {
                MessageBox.Show("斑马标签配置.xml丢失！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                this.Close();
            }

            try
            {
                List<string> list = GetLocalPrinter();
                this.comboBoxPrinter.Items.Clear();
                foreach (string str in list)
                {
                    this.comboBoxPrinter.Items.Add(str);
                }

                iniHistory = new iniOper(configFile);
               // this.comboBoxPrinter.Text = iniHistory.ReadValue("打印机", "General").Replace("\"", "");
                this.comboBoxPrinter.Text = RegistryTool.ReadReg(regkeypath, "袋标打印机");

                int.TryParse(iniHistory.ReadValue("width", "General"), out width);
                int.TryParse(iniHistory.ReadValue("height", "General"), out height);
                image = new Bitmap(width, height);
                gdi = Graphics.FromImage(image);
                gdi.InterpolationMode = InterpolationMode.HighQualityBicubic;

                this.Printer.PrintPage += Printer_PrintPage;

                InitComboBoxByString(this.cb包装线, pimsConfig.GetAppValueByKey("deviceName"));

                if (data!=null)
                {
                    //更新重量及流水号显示
                    XmlReaderSettings settings = new XmlReaderSettings();
                    settings.IgnoreComments = true;
                    XmlReader reader = XmlReader.Create(lableConfigFile, settings);
                    xmlDocument.Load(reader);
                    if (reader != null)
                    {
                        reader.Close();
                    }

                    this.袋标型号.Text = data.Rows[index]["型号"].ToString().Trim();
                    this.袋标粒径.Text = data.Rows[index]["粒径"].ToString().Trim();
                    生产批次号 = data.Rows[index]["生产批次"].ToString().Trim();
                    模板ID = "D"+ (Convert.ToInt16(data.Rows[index]["模板ID"].ToString().Trim())).ToString("D2");
                    UpdateBarcode();
                }
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message+ex.StackTrace);
                this.Close();
            }

        }

        private void InitComboBoxByString(ComboBox comboBox, string value)
        {
            comboBox.Items.Clear();
            string[] strs = value.Split('|');
            for (int i = 0; i < strs.Length; i++)
            {
                comboBox.Items.Add(strs[i]);
            }
        }

        /// <summary>
        /// Resize图片
        /// </summary>
        /// <param name="bmp">原始Bitmap</param> 
        /// <param name="newW">新的宽度</param> 
        /// <param name="newH">新的高度</param> 
        /// <param name="Mode">保留着，暂时未用</param> 
        public static Bitmap KiResizeImage(Bitmap bmp, int newW, int newH, int Mode)
        {
            try
            {
                Bitmap b = new Bitmap(newW, newH);
                Graphics g = Graphics.FromImage(b);

                // 插值算法的质量
                g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                g.DrawImage(bmp, new Rectangle(0, 0, newW, newH), new Rectangle(0, 0, bmp.Width, bmp.Height), GraphicsUnit.Pixel);
                g.Dispose();
                return b;
            }
            catch
            {
                return null;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="g"></param>
        private void CreateLableByXml(Graphics g)
        {
            try
            {
                XmlReaderSettings settings = new XmlReaderSettings();
                settings.IgnoreComments = true;
                XmlReader reader = XmlReader.Create(lableConfigFile, settings);
                xmlDocument.Load(reader);

                XmlNodeList nodeList = xmlDocument.GetElementsByTagName("字段");
                if (reader != null)
                {
                    reader.Close();
                }

                //  this.iwidthLabel = Convert.ToInt16(nodeList[0].Attributes["width"].Value);
                foreach (XmlNode item in nodeList[0].ChildNodes)
                {
                    if (item.Attributes["name"].Value == "QRCODE")
                    {
                        #region
                        this.DrawQRCode(g,
                            item.Attributes["width"].Value,
                            item.Attributes["height"].Value,
                            item.Attributes["x"].Value,
                            item.Attributes["y"].Value
                            );
                        #endregion
                    }
                    else if (item.Attributes["name"].Value == "BARCODE")
                    {
                        #region 本项目里用不到
                        //this.DrawBarcode(g,
                        //    item.Attributes["width"].Value,
                        //    item.Attributes["height"].Value,
                        //    item.Attributes["pureBracode"].Value,
                        //    item.Attributes["x"].Value,
                        //    item.Attributes["y"].Value
                        //    );
                        #endregion
                    }
                    else if (item.Attributes["name"].Value == "LINE")
                    {
                        #region
                        this.DrawLine(g,
                             item.Attributes["penWidth"].Value,
                             item.Attributes["x1"].Value,
                             item.Attributes["y1"].Value,
                             item.Attributes["x2"].Value,
                             item.Attributes["y2"].Value
                             );
                        #endregion
                    }
                    else if (item.Attributes["name"].Value == "LINERECT")
                    {
                        #region
                        this.DrawRect(g,
                             item.Attributes["penWidth"].Value,
                             item.Attributes["x"].Value,
                             item.Attributes["y"].Value,
                             item.Attributes["width"].Value,
                             item.Attributes["height"].Value
                             );
                        #endregion
                    }
                    else if (item.Attributes["name"].Value == "IMAGE")
                    {
                        #region
                        this.DrawImage(g,
                             item.Attributes["value"].Value,
                             item.Attributes["x"].Value,
                             item.Attributes["y"].Value,
                             item.Attributes["width"].Value,
                             item.Attributes["height"].Value
                             );
                        #endregion
                    }
                    else
                    {
                        #region
                        string value = item.Attributes["value"].Value;
                        if (!String.IsNullOrEmpty(item.Attributes["field"].Value))
                        {
                            switch (item.Attributes["field"].Value)
                            {
                                case "型号":
                                    value = this.袋标型号.Text;
                                    break;
                                case "重量":
                                    if (!String.IsNullOrEmpty(this.袋标重量.Text))
                                    {
                                        value = this.袋标重量.Text + "Kg";
                                    }
                                    break;
                                case "粒径":
                                    value = this.袋标粒径.Text;
                                    break;
                            }
                        }
                        if (item.Attributes["x"].Value == "-1")
                        {
                            this.DrawStringCenter(g,
                                item.Attributes["font"].Value,
                                item.Attributes["fontStype"].Value,
                                item.Attributes["size"].Value,
                                value,
                                item.Attributes["x1"].Value,
                                item.Attributes["y"].Value,
                                item.Attributes["width"].Value,
                                item.Attributes["height"].Value
                                 );
                        }
                        else
                        {
                            this.DrawString(g,
                               item.Attributes["font"].Value,
                               item.Attributes["fontStype"].Value,
                               item.Attributes["size"].Value,
                               value,
                               item.Attributes["x"].Value,
                               item.Attributes["y"].Value
                                );
                        }
                        #endregion
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + ex.StackTrace);
            }
        }
        private void DrawString(Graphics g, string fontName, string fontStype, string size, string value, string x, string y)
        {
            FontStyle style = (FontStyle)Enum.Parse(typeof(FontStyle), fontStype);

            Font font = new Font(fontName, Convert.ToSingle(size), style);
            g.DrawString(value, font, Brushes.Black, Convert.ToSingle(x), Convert.ToSingle(y));
        }
        private void DrawStringCenter(Graphics g, string fontName, string fontStype, string size, string value, string x, string y, string width, string height)
        {
            FontStyle style = (FontStyle)Enum.Parse(typeof(FontStyle), fontStype);
            Font font = new Font(fontName, Convert.ToSingle(size), style);

            StringFormat stringFormat = new StringFormat();
            stringFormat.LineAlignment = StringAlignment.Center;
            stringFormat.Alignment = StringAlignment.Center;

            RectangleF lbRect = new RectangleF(
                Convert.ToSingle(x),
                Convert.ToSingle(y),
                Convert.ToSingle(width),
                Convert.ToSingle(height));
            g.DrawString(value, font, Brushes.Black, lbRect, stringFormat);
        }
        private void DrawRect(Graphics g, string penWidth, string x, string y, string width, string height)
        {
            float fwidth = 1.0f;
            float.TryParse(penWidth, out fwidth);
            Pen pen = new Pen(Brushes.Black, fwidth);

            g.DrawRectangle(pen, Convert.ToInt16(x), Convert.ToInt16(y), Convert.ToInt16(width), Convert.ToInt16(height));
        }
        private void DrawLine(Graphics g, string penWidth, string x1, string y1, string x2, string y2)
        {
            float fwidth = 1.0f;
            float.TryParse(penWidth, out fwidth);
            Pen pen = new Pen(Brushes.Black, fwidth);

            g.DrawLine(pen, Convert.ToInt16(x1), Convert.ToInt16(y1), Convert.ToInt16(x2), Convert.ToInt16(y2));
        }
        private void DrawBarcode(Graphics g, string width, string height, string pureBracode, string x, string y)
        {
            int iwidth = 240;
            int iheight = 40;
            int ix = 4;
            int iy = 110;
            int.TryParse(width, out iwidth);
            int.TryParse(height, out iheight);
            int.TryParse(x, out ix);
            int.TryParse(y, out iy);

            if (pureBracode == "1")
            {
                // g.DrawImageUnscaled(BarCode(labelinfo.codebar, iwidth, iheight, true), ix, iy);
            }
            else
            {
                // g.DrawImageUnscaled(BarCode(labelinfo.codebar, iwidth, iheight, false), ix, iy);
            }
        }
        private void DrawQRCode(Graphics g, string width, string height, string x, string y)
        {
            int iwidth = 550;
            int iheight = 550;
            int ix = 4;
            int iy = 110;
            int.TryParse(width, out iwidth);
            int.TryParse(height, out iheight);
            int.TryParse(x, out ix);
            int.TryParse(y, out iy);

            this.qrBmp = ZxingQRCode.GenerateQRCode(barcode, iwidth, iheight);
            g.DrawImage(this.qrBmp, ix, iy, iwidth, iheight);
        }
        private void DrawImage(Graphics g, string value, string x, string y, string width, string height)
        {
            int iwidth = 28;
            int iheight = 28;
            int ix = 6;
            int iy = 7;
            int.TryParse(width, out iwidth);
            int.TryParse(height, out iheight);
            int.TryParse(x, out ix);
            int.TryParse(y, out iy);

            if (value == "daibiao1")
                g.DrawImage(PIMS.WorkPlugin.Properties.Resources.daibiao, ix, iy, iwidth, iheight);
        }
        /// <summary>
        /// Zing
        /// </summary>
        /// <param name="Contents"></param>
        /// <returdns></returns>
        private Bitmap BarCode(string Contents, int width = 250, int height = 50, bool pureBracode = false)
        {
            EncodingOptions options = new EncodingOptions();
            options.Width = width; //276-246
            options.Height = height;
            options.PureBarcode = pureBracode; //true
            BarcodeWriter writer = new BarcodeWriter();
            writer.Format = BarcodeFormat.CODE_128;
            writer.Options = options;
            return writer.Write(Contents);
        }


        private void btn_Close_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void btn_Print_Click(object sender, EventArgs e)
        {
            if(this.data==null)
            {
                MessageBox.Show("无有效数据！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            if(this.tb_Bit5.Text=="0" && 
               this.tb_Bit4.Text=="0" &&
                this.tb_Bit3.Text=="0" &&
                this.tb_Bit2.Text=="0" &&
                this.tb_Bit1.Text=="0")
            {
                MessageBox.Show("请设置流水号再打印！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            //指定打印机，非默认
            Printer.PrinterSettings.PrinterName = this.comboBoxPrinter.Text; //"Microsoft XPS Document Writer";
            //加入注释
            Printer.PrinterSettings.PrintToFile = true;
            Printer.Print();

            this.Close();
        }

        void Printer_PrintPage(object sender, PrintPageEventArgs e)
        {
            ////横向打印，还要设置打印机属性里纸张为横向
            //e.PageSettings.Landscape = true;
            ////e.Graphics.DrawImageUnscaled(this.image, 0, 0);
            //this.CreateLableByXml(e.Graphics);
            this.CreateLableByXml(e.Graphics);
        }

        private void comboBoxPrinter_SelectedIndexChanged(object sender, EventArgs e)
        {
            //if (!String.IsNullOrEmpty(this.comboBoxPrinter.Text) && iniHistory != null)
            // iniHistory.Write("General", "打印机", "\"" + this.comboBoxPrinter.Text + "\"");

            if (!String.IsNullOrEmpty(this.comboBoxPrinter.Text))
              RegistryTool.WriteReg(regkeypath, "袋标打印机", this.comboBoxPrinter.Text);
        }

        /// <summary>
        ///  获取本地打印机的列表，第一项就是默认打印机
        /// </summary>
        public static List<string> GetLocalPrinter()
        {
            List<string> fPrinters = new List<string>();
            foreach (string fPrinterName in PrinterSettings.InstalledPrinters)
            {
                if (!fPrinters.Contains(fPrinterName))
                    fPrinters.Add(fPrinterName);
            }
            return fPrinters;
        }

        #region Add and Sub
        private void btn_Add1_Click(object sender, EventArgs e)
        {
            MyAdd(this.tb_Bit1);
        }

        private void btn_Sub1_Click(object sender, EventArgs e)
        {
            MySub(this.tb_Bit1);
        }

        private void btn_Add2_Click(object sender, EventArgs e)
        {
            MyAdd(this.tb_Bit2);
        }

        private void btn_Sub2_Click(object sender, EventArgs e)
        {
            MySub(this.tb_Bit2);
        }

        private void btn_Add3_Click(object sender, EventArgs e)
        {
            MyAdd(this.tb_Bit3);
        }

        private void btn_Sub3_Click(object sender, EventArgs e)
        {
            MySub(this.tb_Bit3);
        }

        private void btn_Add4_Click(object sender, EventArgs e)
        {
            MyAdd(this.tb_Bit4);
        }

        private void btn_Sub4_Click(object sender, EventArgs e)
        {
            MySub(this.tb_Bit4);
        }

        private void btn_Add5_Click(object sender, EventArgs e)
        {
            MyAdd(this.tb_Bit5);
        }

        private void btn_Sub5_Click(object sender, EventArgs e)
        {
            MySub(this.tb_Bit5);
        }

        private void MyAdd(TextBox tb)
        {
            int count = Convert.ToInt16(tb.Text);
            count++;
            if (count > 9) count = 9;
            tb.Text = count.ToString();
            UpdateBarcode();
        }

        private void MySub(TextBox tb)
        {
            int count = Convert.ToInt16(tb.Text);
            count--;
            if (count <0) count = 0;
            tb.Text = count.ToString();
            UpdateBarcode();
        }

        #endregion

        /// <summary>
        /// X2P321092800001,D26,YX-B-26-201011
        /// </summary>
        /// <returns></returns>
        private void UpdateBarcode()
        {
            this.二维码值.Text = string.Concat(new string[] 
          { 
             this.head,
             this.dateTimePicker1.Value.ToString("yyMMdd"),
             this.tb_Bit5.Text,
             this.tb_Bit4.Text,
             this.tb_Bit3.Text,
             this.tb_Bit2.Text,
             this.tb_Bit1.Text
          });
            barcode = string.Concat(new string[] 
          { 
             this.二维码值.Text,
             ",",
             this.模板ID,
              ",",
             this.生产批次号
          });

            this.CreateLableByXml(gdi);
            image.Save(AppDomain.CurrentDomain.BaseDirectory + "temp.bmp");
            this.pictureBox1.Image = KiResizeImage(image, this.pictureBox1.Width, this.pictureBox1.Height, 0);
        }

        private void dateTimePicker1_ValueChanged(object sender, EventArgs e)
        {
            if (image == null)
                return;
            UpdateBarcode();

        }

        private void cb包装线_SelectedIndexChanged(object sender, EventArgs e)
        {
            if(!String.IsNullOrEmpty(cb包装线.Text))
            {
                string where = string.Format("packager='{0}'", cb包装线.Text);
                DataTable dt = SqlSugarHelper.QueryToDataTable<orderformcurrent>(where, 1);
                if(dt !=null)
                {
                    this.袋标型号.Text = dt.Rows[0]["productName"].ToString();
                    this.袋标粒径.Text = dt.Rows[0]["productMark"].ToString();
                    this.head = "Y2P" + dt.Rows[0]["id"].ToString();

                    this.生产批次号 = dt.Rows[0]["batchNo"].ToString();
                    this.模板ID = dt.Rows[0]["reserved3"].ToString().PadLeft(2,'0');

                    this.data = dt;
                }
            }
        }
    }
}
